From 3e213e5435414aaf0610f407c0c529eccff4998b Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 22 Nov 2007 19:55:42 +0000 Subject: [PATCH] hvm: Clean up VMCS/VMCB construction. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/svm/vmcb.c | 38 ++++++----------- xen/arch/x86/hvm/vmx/vmcs.c | 67 +++++++++++------------------- xen/include/asm-x86/hvm/svm/vmcb.h | 3 +- 3 files changed, 39 insertions(+), 69 deletions(-) diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c index 2332581ed6..563e481833 100644 --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -40,8 +40,6 @@ extern int svm_dbg_on; -#define GUEST_SEGMENT_LIMIT 0xffffffff - #define IOPM_SIZE (12 * 1024) #define MSRPM_SIZE (8 * 1024) @@ -110,7 +108,6 @@ static int construct_vmcb(struct vcpu *v) { struct arch_svm_struct *arch_svm = &v->arch.hvm_svm; struct vmcb_struct *vmcb = arch_svm->vmcb; - svm_segment_attributes_t attrib; /* TLB control, and ASID assigment. */ svm_asid_init_vcpu(v); @@ -173,12 +170,12 @@ static int construct_vmcb(struct vcpu *v) vmcb->efer = EFER_SVME; /* Guest segment limits. */ - vmcb->cs.limit = GUEST_SEGMENT_LIMIT; - vmcb->es.limit = GUEST_SEGMENT_LIMIT; - vmcb->ss.limit = GUEST_SEGMENT_LIMIT; - vmcb->ds.limit = GUEST_SEGMENT_LIMIT; - vmcb->fs.limit = GUEST_SEGMENT_LIMIT; - vmcb->gs.limit = GUEST_SEGMENT_LIMIT; + vmcb->cs.limit = ~0u; + vmcb->es.limit = ~0u; + vmcb->ss.limit = ~0u; + vmcb->ds.limit = ~0u; + vmcb->fs.limit = ~0u; + vmcb->gs.limit = ~0u; /* Guest segment bases. */ vmcb->cs.base = 0; @@ -189,20 +186,12 @@ static int construct_vmcb(struct vcpu *v) vmcb->gs.base = 0; /* Guest segment AR bytes. */ - attrib.bytes = 0; - attrib.fields.type = 0x3; /* type = 3 */ - attrib.fields.s = 1; /* code or data, i.e. not system */ - attrib.fields.dpl = 0; /* DPL = 0 */ - attrib.fields.p = 1; /* segment present */ - attrib.fields.db = 1; /* 32-bit */ - attrib.fields.g = 1; /* 4K pages in limit */ - vmcb->es.attr = attrib; - vmcb->ss.attr = attrib; - vmcb->ds.attr = attrib; - vmcb->fs.attr = attrib; - vmcb->gs.attr = attrib; - attrib.fields.type = 0xb; /* type=0xb -> executable/readable, accessed */ - vmcb->cs.attr = attrib; + vmcb->es.attr.bytes = 0xc93; /* read/write, accessed */ + vmcb->ss.attr.bytes = 0xc93; + vmcb->ds.attr.bytes = 0xc93; + vmcb->fs.attr.bytes = 0xc93; + vmcb->gs.attr.bytes = 0xc93; + vmcb->cs.attr.bytes = 0xc9b; /* exec/read, accessed */ /* Guest IDT. */ vmcb->idtr.base = 0; @@ -219,8 +208,7 @@ static int construct_vmcb(struct vcpu *v) vmcb->ldtr.attr.bytes = 0; /* Guest TSS. */ - attrib.fields.type = 0xb; /* 32-bit TSS (busy) */ - vmcb->tr.attr = attrib; + vmcb->tr.attr.bytes = 0x08b; /* 32-bit TSS (busy) */ vmcb->tr.base = 0; vmcb->tr.limit = 0xff; diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 03cf5cbc92..3a184c55ba 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -443,11 +443,8 @@ void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr) } } -#define GUEST_SEGMENT_LIMIT 0xffffffff - static int construct_vmcs(struct vcpu *v) { - union vmcs_arbytes arbytes; uint16_t sysenter_cs; unsigned long sysenter_eip; @@ -537,46 +534,39 @@ static int construct_vmcs(struct vcpu *v) __vmwrite(GUEST_CS_BASE, 0); /* Guest segment limits. */ - __vmwrite(GUEST_ES_LIMIT, GUEST_SEGMENT_LIMIT); - __vmwrite(GUEST_SS_LIMIT, GUEST_SEGMENT_LIMIT); - __vmwrite(GUEST_DS_LIMIT, GUEST_SEGMENT_LIMIT); - __vmwrite(GUEST_FS_LIMIT, GUEST_SEGMENT_LIMIT); - __vmwrite(GUEST_GS_LIMIT, GUEST_SEGMENT_LIMIT); - __vmwrite(GUEST_CS_LIMIT, GUEST_SEGMENT_LIMIT); + __vmwrite(GUEST_ES_LIMIT, ~0u); + __vmwrite(GUEST_SS_LIMIT, ~0u); + __vmwrite(GUEST_DS_LIMIT, ~0u); + __vmwrite(GUEST_FS_LIMIT, ~0u); + __vmwrite(GUEST_GS_LIMIT, ~0u); + __vmwrite(GUEST_CS_LIMIT, ~0u); /* Guest segment AR bytes. */ - arbytes.bytes = 0; - arbytes.fields.seg_type = 0x3; /* type = 3 */ - arbytes.fields.s = 1; /* code or data, i.e. not system */ - arbytes.fields.dpl = 0; /* DPL = 3 */ - arbytes.fields.p = 1; /* segment present */ - arbytes.fields.default_ops_size = 1; /* 32-bit */ - arbytes.fields.g = 1; - arbytes.fields.null_bit = 0; /* not null */ - __vmwrite(GUEST_ES_AR_BYTES, arbytes.bytes); - __vmwrite(GUEST_SS_AR_BYTES, arbytes.bytes); - __vmwrite(GUEST_DS_AR_BYTES, arbytes.bytes); - __vmwrite(GUEST_FS_AR_BYTES, arbytes.bytes); - __vmwrite(GUEST_GS_AR_BYTES, arbytes.bytes); - arbytes.fields.seg_type = 0xb; /* type = 0xb */ - __vmwrite(GUEST_CS_AR_BYTES, arbytes.bytes); + __vmwrite(GUEST_ES_AR_BYTES, 0xc093); /* read/write, accessed */ + __vmwrite(GUEST_SS_AR_BYTES, 0xc093); + __vmwrite(GUEST_DS_AR_BYTES, 0xc093); + __vmwrite(GUEST_FS_AR_BYTES, 0xc093); + __vmwrite(GUEST_GS_AR_BYTES, 0xc093); + __vmwrite(GUEST_CS_AR_BYTES, 0xc09b); /* exec/read, accessed */ + + /* Guest IDT. */ + __vmwrite(GUEST_IDTR_BASE, 0); + __vmwrite(GUEST_IDTR_LIMIT, 0); /* Guest GDT. */ __vmwrite(GUEST_GDTR_BASE, 0); __vmwrite(GUEST_GDTR_LIMIT, 0); - /* Guest IDT. */ - __vmwrite(GUEST_IDTR_BASE, 0); - __vmwrite(GUEST_IDTR_LIMIT, 0); + /* Guest LDT. */ + __vmwrite(GUEST_LDTR_AR_BYTES, 0x0082); /* LDT */ + __vmwrite(GUEST_LDTR_SELECTOR, 0); + __vmwrite(GUEST_LDTR_BASE, 0); + __vmwrite(GUEST_LDTR_LIMIT, 0); - /* Guest LDT and TSS. */ - arbytes.fields.s = 0; /* not code or data segement */ - arbytes.fields.seg_type = 0x2; /* LTD */ - arbytes.fields.default_ops_size = 0; /* 16-bit */ - arbytes.fields.g = 0; - __vmwrite(GUEST_LDTR_AR_BYTES, arbytes.bytes); - arbytes.fields.seg_type = 0xb; /* 32-bit TSS (busy) */ - __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes); + /* Guest TSS. */ + __vmwrite(GUEST_TR_AR_BYTES, 0x008b); /* 32-bit TSS (busy) */ + __vmwrite(GUEST_TR_BASE, 0); + __vmwrite(GUEST_TR_LIMIT, 0xff); __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0); __vmwrite(GUEST_DR7, 0); @@ -600,13 +590,6 @@ static int construct_vmcs(struct vcpu *v) __vmwrite(TPR_THRESHOLD, 0); } - __vmwrite(GUEST_LDTR_SELECTOR, 0); - __vmwrite(GUEST_LDTR_BASE, 0); - __vmwrite(GUEST_LDTR_LIMIT, 0); - - __vmwrite(GUEST_TR_BASE, 0); - __vmwrite(GUEST_TR_LIMIT, 0xff); - vmx_vmcs_exit(v); paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */ diff --git a/xen/include/asm-x86/hvm/svm/vmcb.h b/xen/include/asm-x86/hvm/svm/vmcb.h index 35e492f36a..b5487fc491 100644 --- a/xen/include/asm-x86/hvm/svm/vmcb.h +++ b/xen/include/asm-x86/hvm/svm/vmcb.h @@ -303,8 +303,7 @@ enum VMEXIT_EXITCODE VMEXIT_INVALID = -1 }; -/* Definitions of segment state are borrowed by the generic HVM code. */ -typedef segment_attributes_t svm_segment_attributes_t; +/* Definition of segment state is borrowed by the generic HVM code. */ typedef segment_register_t svm_segment_register_t; typedef union -- 2.30.2